#include "fpga_drv.h"

#include <errno.h>

#include <stdint.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <getopt.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/types.h>
#include <linux/spi/spidev.h>
#include <sys/types.h>
#include <dirent.h>
#include "../utils/utils.h"

#include "fpga_manage.h"
#include "../global/BxGlobal.h"


#define DRVFPGA_VBYNE1_SPIDRV_FILE_NAME "/dev/spidev4.1"
// #define DRVFPGA_VBYNE2_SPIDRV_FILE_NAME "/dev/spidev32766.2"
#define DRVFPGA_VBYNE1_FLASHSPIDRV_FILE_NAME "/dev/spidev4.0"
// #define DRVFPGA_VBYNE2_FLASHSPIDRV_FILE_NAME "/dev/spidev32766.4"
// #define DRVFPGA_IRQ_VBYONE_FILE_NAME   "/dev/input/event2"
//#define DRV_FPGA1_IRQ_VBYONE_NAME "/sys/class/gpio/gpio87/value"
//#define DRV_FPGA2_IRQ_VBYONE_NAME "/sys/class/gpio/gpio89/value"


fpga_drv::fpga_drv()
{
    BX_printf("====fpga_drv::fpga_drv()=====\n") ;

}


fpga_drv::~fpga_drv()
{

}

#if 0
int fpga_drv::get_fpga_irq_fd(Ouint8 sel)
{
    int fd;
#if 0
    struct  input_event event;


    char          name[64];           /* RATS: Use ok, but could be better */
        char          buf[256] = { 0, };  /* RATS: Use ok */
        unsigned char mask[EV_MAX/8 + 1]; /* RATS: Use ok */
        int           version;
        int           rc;
        int           i, j;
        char          *tmp;



//    fd = open(DRVFPGA_IRQ_VBYONE_FILE_NAME, O_RDONLY|O_NONBLOCK);
    fd = open(DRVFPGA_IRQ_VBYONE_FILE_NAME, O_RDONLY);

    BX_printf("\n ===fpga_drv::get_fpga_irq_fd=====(%d)  \n",fd) ;



    ioctl(fd, EVIOCGVERSION, &version);
    ioctl(fd, EVIOCGNAME(sizeof(buf)), buf);
    ioctl(fd, EVIOCGBIT(0, sizeof(mask)), mask);
    printf("%s\n", name);
    printf("    evdev version: %d.%d.%d\n",
           version >> 16, (version >> 8) & 0xff, version & 0xff);
    printf("    name: %s\n", buf);
    printf("    features:");
//    for (j = 0; j < EV_MAX; j++) {
//        if (test_bit(j)) {
//            const char *type = "unknown";
//            switch(j) {
//            case EV_KEY: type = "keys/buttons"; break;
//            case EV_REL: type = "relative";     break;
//            case EV_ABS: type = "absolute";     break;
//            case EV_MSC: type = "reserved";     break;
//            case EV_LED: type = "leds";         break;
//            case EV_SND: type = "sound";        break;
//            case EV_REP: type = "repeat";       break;
//            case EV_FF:  type = "feedback";     break;
//            }
//            printf(" %s", type);
//        }
//    }
    printf("\n");
#else

    if(sel == FPGA_MASTER_VBYONE1){
        fd = open(DRV_FPGA1_IRQ_VBYONE_NAME,O_RDONLY) ;

        BX_printf("\n open fpga1 irq = %#x \n",fd ) ;
    }else if(sel == FPGA_MASTER_VBYONE2){
        fd = open(DRV_FPGA2_IRQ_VBYONE_NAME,O_RDONLY) ;
    }

#endif
#if 0
    event.time.tv_sec = time( 0);
    event.time.tv_usec = 0;
    event.type = EV_KEY;
    event.code = i;
    event.value = 0;
    write(fd, &event, sizeof(event));
#endif

    return fd ;

}
#endif
#if 0
void fpga_drv::close_fpga_irq_fd(int fd)
{


    //close(fd);

    //BX_printf("\n ===fpga_drv::close_fpga_irq_fd=====(%d)  \n",fd) ;


}
#endif



int fpga_drv::initialize_vbyne1(Ouint8 sel)
{
    int ret;
    int fd ;
    unsigned char mode  = 0x03;
    unsigned char bits = 0x08;                      //8bit to RW
    unsigned int speed = 1000*1000;
    unsigned int rd_speed = 1000*1000;            // read speed

    BX_printf("initialize_vbyne1\n");

    if(sel ==FPGA_MASTER_VBYONE1 ) {

        fd = open(DRVFPGA_VBYNE1_SPIDRV_FILE_NAME, O_RDWR);
    }else if(sel ==FPGA_MASTER_VBYONE2 ){

        // fd = open(DRVFPGA_VBYNE2_SPIDRV_FILE_NAME, O_RDWR);
    }else if(sel ==FPGA_FLASH_VBYONE1){
        fd = open(DRVFPGA_VBYNE1_FLASHSPIDRV_FILE_NAME, O_RDWR);
    }else if(sel ==FPGA_FLASH_VBYONE2){
        // fd = open(DRVFPGA_VBYNE2_FLASHSPIDRV_FILE_NAME, O_RDWR);
    }


    if(ret < 0){
        BX_printf("\ncan't open device\n");
    }else{
        BX_printf("\n fpga_drv SPI - Open Succeed. Start Init SPI...\n");
    }
//    BX_printf("fpga_drv fd = %02x \n",ret) ;

    /*
     * spi mode
     */
    ret = ioctl(fd, SPI_IOC_WR_MODE, &mode); //0 CPOL=0,CPHA=0;
    if (ret == -1)//{
        perror("can't set spi mode  \n");
    //}
    ret = ioctl(fd, SPI_IOC_RD_MODE, &mode);
    if (ret == -1){
        BX_printf("can't get spi mode\n");
    }
    /*
    * bits per word
    */
    ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits);
    if (ret == -1){
        BX_printf("can't set bits per word\n");
    }
    ret = ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits);
    if (ret == -1){
        BX_printf("can't get bits per word\n");
    }
#if 0
    /*
     * max speed hz
     */
    ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed);
    if (ret == -1){
        BX_printf("can't set max speed hz\n");
    }
    ret = ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &rd_speed);
    if (ret == -1){
        BX_printf("can't get max speed hz\n");
    }
    //BX_printf(" fpga_drv spi mode: %d\n", mode);
    //BX_printf(" fpga_drv bits per word: %d\n", bits);
    //BX_printf(" fpga_drv max speed: %d KHz (%d MHz)\n", speed / 1000, speed / 1000 / 1000);
    //BX_printf(" fpga_drv max rdspeed: %d KHz (%d MHz)\n", rd_speed / 1000, rd_speed / 1000 / 1000);
#endif

#if 0
    //fpga may need cmd/data
    if(sel ==FPGA_MASTER_VBYONE1){
        if( opendir("/sys/class/gpio/gpio85") ==  NULL) {
            usleep(1000*10) ;
            system("echo 85 > /sys/class/gpio/export") ;
            usleep(1000*10) ;
            system("echo out > /sys/class/gpio/gpio85/direction");
            usleep(1000*10) ;
            BX_printf("\n system GPIO_14 \n");
        }

        if( opendir("/sys/class/gpio/gpio14") ==  NULL) {
            usleep(1000*10) ;
            system("echo 14 > /sys/class/gpio/export") ;
            usleep(1000*10) ;
            system("echo out > /sys/class/gpio/gpio14/direction");
            usleep(1000*10) ;
            BX_printf("\n system GPIO_14 \n");
        }

        if( opendir("/sys/class/gpio/gpio4") ==  NULL) {
            usleep(1000*10) ;
            system("echo 4 > /sys/class/gpio/export") ;
            usleep(1000*10) ;
            system("echo out > /sys/class/gpio/gpio4/direction");
            usleep(1000*10) ;
            BX_printf("\n system GPIO_4 \n");
        }


        if( opendir("/sys/class/gpio/gpio17") ==  NULL) {
            usleep(1000*10) ;
            system("echo 17 > /sys/class/gpio/export") ;
            usleep(1000*10) ;
            system("echo out > /sys/class/gpio/gpio17/direction");
            usleep(1000*10) ;
            system("echo 1 >/sys/class/gpio/gpio17/value");
            usleep(1000*10) ;
            BX_printf("\n system GPIO_17 \n");
        }else{
            system("echo 1 >/sys/class/gpio/gpio17/value");
            usleep(1000*10) ;
        }

    }

    if(sel ==FPGA_MASTER_VBYONE2){
        if( opendir("/sys/class/gpio/gpio56") ==  NULL) {
            usleep(1000*10) ;
            system("echo 56 > /sys/class/gpio/export") ;
            usleep(1000*10) ;
            system("echo out > /sys/class/gpio/gpio56/direction");
            usleep(1000*10) ;
           // BX_printf("\n system GPIO_56 \n");

        }

        if( opendir("/sys/class/gpio/gpio48") ==  NULL) {
            usleep(1000*10) ;
            system("echo 48 > /sys/class/gpio/export") ;
            usleep(1000*10) ;
            system("echo out > /sys/class/gpio/gpio48/direction");
            usleep(1000*10) ;
            system("echo 1 >/sys/class/gpio/gpio48/value");
            usleep(1000*10) ;
            BX_printf("\n system GPIO_48 \n");
        }else{
            system("echo 1 >/sys/class/gpio/gpio48/value");
            usleep(1000*10) ;
        }
    }


    if(sel ==FPGA_FLASH_VBYONE1){
        if( opendir("/sys/class/gpio/gpio47") ==  NULL) {
            usleep(1000*10) ;
            system("echo 47 > /sys/class/gpio/export") ;
            usleep(1000*10) ;
            system("echo out > /sys/class/gpio/gpio47/direction");
            usleep(1000*10) ;
            system("echo 1 >/sys/class/gpio/gpio47/value");
            usleep(1000*10) ;
            BX_printf("\n system GPIO_47 \n");
        }else{
            system("echo 1 >/sys/class/gpio/gpio47/value");
            usleep(1000*10) ;
            BX_printf("\n system GPIO_47 \n");
        }

    }

    if(sel ==FPGA_FLASH_VBYONE2){
        //flash sel
        if( opendir("/sys/class/gpio/gpio88") ==  NULL) {
            usleep(1000*10) ;
            system("echo 88 > /sys/class/gpio/export") ;
            usleep(1000*10) ;
            system("echo out > /sys/class/gpio/gpio88/direction");
            usleep(1000*10) ;
            system("echo 1 >/sys/class/gpio/gpio88/value");
            usleep(1000*10) ;
            BX_printf("\n system GPIO_88 \n");
        }else{
            system("echo 1 >/sys/class/gpio/gpio88/value");
            usleep(1000*10) ;
            BX_printf("\n system GPIO_47 \n");
        }
    }

    //FPGA FLASH SEL
#endif




    return fd;
}


int fpga_drv::SPI_Transfer(int fd ,const unsigned char *TxBuf, unsigned char *RxBuf, Ouint32 len)
{
    int ret;
    struct spi_ioc_transfer tr ={
        .tx_buf = (unsigned long) TxBuf,
        .rx_buf = (unsigned long) RxBuf,
        .len = len,
        .speed_hz = 1000000,
        .delay_usecs = 0,
        //.speed_hz = 5000000,
        .bits_per_word = 8,

        .cs_change = 0,
        // .tx_nbits = 0,
        // .rx_nbits = 0,
        .pad = 0

    };
    //Utils::_spi_mutex.lock();
    ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);
    //Utils::_spi_mutex.unlock();
    if (ret < 1)
        perror("can't send spi message\n");

#if 0
    else
    {

        int i;
        BX_printf("nsend spi message Succeed\n");
        BX_printf("nSPI Send [Len:%d]: \n", len);
        for (i = 0; i < len; i++)
        {
        if (i % 8 == 0)
            printf("nt\n");
            printf("0x%02X \n", TxBuf[i]);
        }
        BX_printf("n");

        if(RxBuf == NULL){
            return 0;
        }

        BX_printf("SPI Receive [len:%d]:\n", len);
        for (i = 0; i < len; i++)
        {
            if (i % 8 == 0)
                BX_printf("nt\n");
            BX_printf("0x%02X \n", RxBuf[i]);
        }
        BX_printf("\n");

    }
#endif

    return ret;
}




int fpga_drv::SPI_Transfer_Write(int fd ,const unsigned char *TxBuf,Ouint32 len)
{
    int ret;

    struct spi_ioc_transfer tr ={
        .tx_buf = (unsigned long) TxBuf,
        .rx_buf = 0,
        .len = len,
        .speed_hz = 1000000,
        .delay_usecs = 0,
        //.speed_hz = 5000000,
        .bits_per_word = 8,

        .cs_change = 0,
        // .tx_nbits = 0,
        // .rx_nbits = 0,
        .pad = 0

    };
    //Utils::_spi_mutex.lock();
    ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);
    //Utils::_spi_mutex.unlock();
    if (ret < 1)
        perror("can't send spi message\n");
//#if SPI_DEBUG
    else
    {

//        int i;
//        BX_printf("nsend spi message Succeed\n");
//        BX_printf("nSPI Send [Len:%d]: \n", len);
//        for (i = 0; i < len; i++)
//        {
//        if (i % 8 == 0)
//            BX_printf("nt\n");
//            BX_printf("0x%02X \n", TxBuf[i]);
//        }
//        BX_printf("n");

    }
//#endif

    return ret;
}


/**
 * @brief FPGA_SPI_Disable_WP
 *
 * @param fd: fd
 * @return
 */
void fpga_drv::FPGA_SPI_Disable_WP(int fd)
{
    //unsigned char Txbuf[2] = {SPI_FLASH_CMD_READ_STATUS1,0xff} ;
    unsigned char RxBuf[2]={0} ;
    int ret = 0;
    unsigned char txbuf[4] ;

//    system("echo 0 >/sys/class/gpio/gpio85/value");

    //BACK_FPGA1_FLASH();
//    SEL_FPGA2_FLASH(); //GPI047
//    usleep(10);

    //if(name == FPGA_MASTER_VBYONE1){
//        system("echo 0 >/sys/class/gpio/gpio47/value");
   // }else{
       // system("echo 0 >/sys/class/gpio/gpio88/value");
   // }




    txbuf[0] = SPI_FLASH_CMD_WRITE_ENABLE ;
    SPI_Transfer_Write(fd,txbuf,1) ;
    //usleep(10);
    txbuf[0] = SPI_FLASH_CMD_WRITE_STATUS1 ;
    txbuf[1] = 0xff;
    txbuf[2] = 0xff;
    SPI_Transfer_Write(fd,txbuf,3) ;

    //usleep(10);
    txbuf[0] = SPI_FLASH_CMD_READ_STATUS1 ;
    txbuf[0] = 0xff ;
    RxBuf[1] = 0;
    ret = SPI_Transfer(fd,txbuf,RxBuf,2) ;
    BX_printf("\n FPGA_SPI_Disable_WP  01 busy=%#x \n",RxBuf[1]) ;


    txbuf[0] = SPI_FLASH_CMD_WRITE_ENABLE ;
    SPI_Transfer_Write(fd,txbuf,1) ;

    txbuf[0] = SPI_FLASH_CMD_WRITE_STATUS2 ;
    txbuf[1] = 0x00;
    SPI_Transfer_Write(fd,txbuf,2) ;

    txbuf[0] = SPI_FLASH_CMD_WRITE_ENABLE ;
    SPI_Transfer_Write(fd,txbuf,1) ;


    txbuf[0] = SPI_FLASH_CMD_READ_STATUS1 ;
    txbuf[0] = 0xff ;
    RxBuf[1] = 0;
    ret = SPI_Transfer(fd,txbuf,RxBuf,2) ;
    BX_printf("\n FPGA_SPI_Disable_WP  02  busy=%#x \n",RxBuf[1]) ;



    txbuf[0] = SPI_FLASH_CMD_WRITE_ENABLE ;
    SPI_Transfer_Write(fd,txbuf,1) ;


    txbuf[0] = SPI_FLASH_CMD_READ_STATUS1 ;
    txbuf[0] = 0xff ;
    RxBuf[1] = 0;
    ret = SPI_Transfer(fd,txbuf,RxBuf,2) ;
    BX_printf("\n FPGA_SPI_Disable_WP  03  busy=%#x \n",RxBuf[1]) ;


    txbuf[0] = SPI_FLASH_CMD_READ_STATUS1 ;
    txbuf[0] = 0xff ;
    RxBuf[1] = 0;
    ret = SPI_Transfer(fd,txbuf,RxBuf,2) ;
    BX_printf("\n FPGA_SPI_Disable_WP  04  busy=%#x \n",RxBuf[1]) ;
}



/**
 * @brief FPGA_SPI_WAIT_BUSY
 *
 * @param fd: fd
 * @return
 */
void fpga_drv::FPGA_SPI_WAIT_BUSY(int fd)
{
//    unsigned char Txbuf[3] = {SPI_FLASH_CMD_READ_STATUS1,0xff,0xFF} ;
//    unsigned char RxBuf[3]={0} ;
    int ret = 0;
    //int i = 0;

    unsigned char * Txbuf = new unsigned char[8 + 5];
    unsigned char *RxBuf = new unsigned char[8 + 5] ;

//    for(i = 0 ; i< 200000 ; i++){
//        Txbuf[0] = SPI_FLASH_CMD_READ_STATUS1;
//        Txbuf[1] = 0xff;

//        ret = SPI_Transfer(fd,Txbuf,RxBuf,2) ;
//        if((RxBuf[1]&0x01) == 0){
//            break;

//        }
//        //BX_printf("\n FPGA_SPI_WAIT_BUSY  ret = %#x , %#x\n",ret,RxBuf[1]) ;
//        usleep(10);
//    }

 //   BX_printf("\n FPGA_SPI_WAIT_BUSY  ret = %#x , %#x\n",ret,RxBuf[1]) ;


//    system("echo 0 >/sys/class/gpio/gpio85/value");

    //BACK_FPGA1_FLASH();
//    SEL_FPGA2_FLASH(); //GPI047
//    usleep(10);


//     system("echo 0 >/sys/class/gpio/gpio47/value");



    do{
        Txbuf[0] = SPI_FLASH_CMD_READ_STATUS1;
        Txbuf[1] = 0xff;
        Txbuf[2] = 0xff;
        RxBuf[0] = 0xFF;
        RxBuf[1] = 0xFF;
        RxBuf[2] = 0xFF;

        ret = SPI_Transfer(fd,Txbuf,RxBuf,2) ;


    }while((RxBuf[1]&0x01) > 0);


    delete Txbuf;
    delete RxBuf;

}





/**
 * @brief FPGA_SPI_FLASH_VBYONE_ERASE
 *
 * @param fd: fd
 * @param name: vbyone1/vbyone2
 * @param sec: sec of flash
 * @param mode: SPI_FLASH_CMD_ERASE_4K/SPI_FLASH_CMD_ERASE_32K/SPI_FLASH_CMD_ERASE_64K
 * @param num:num of sec
 * @return
 */
Ouint8 fpga_drv::FPGA_SPI_FLASH_VBYONE_ERASE(Ouint8 name,Ouint32 sec, Ouint8 mode,Ouint32 num)
{
    Ouint8 cmd[3]={SPI_FLASH_CMD_ERASE_4K,SPI_FLASH_CMD_ERASE_32K,SPI_FLASH_CMD_ERASE_64K};
    Ouint8 size[3]={1,8,16};
    Ouint32 i,ssec,StartAddr = 0;
    unsigned char txbuf[4] ;
    //unsigned char rxbuf[4];
    int fd;

    //tempCmd = cmd[mode];
    ssec = sec;
    if (sec+ size[mode]*num > g_Global->FPGA_FLASH_VBYONE1_MAX_ADDR || mode >= 3) return FALSE;
    Utils::_spi_mutex.lock();
    //system("echo 0 >/sys/class/gpio/gpio85/value");


    //BACK_FPGA1_FLASH();
//    SEL_FPGA2_FLASH(); //GPI047
//    usleep(10);

    if(name == FPGA_FLASH_VBYONE1){
        fd = fpga_manage::p_fpga_manage->fpga_vbyone1_flash_fd ;
        // *(unsigned short *)fpga_manage::p_fpga_manage->to_fpga1_spi_flash_sel =  GPIO47_CONTENT_L;
        g_FpgaManage->setGpioHigLow(3, 1, 0);

    }
 // Utils::_system_mutex.unlock();

    //FPGA_SPI_Disable_WP(fd);
    FPGA_SPI_WAIT_BUSY(fd) ;

    for(i = 0;i<num;i++){

        txbuf[0] = SPI_FLASH_CMD_WRITE_ENABLE ;
        SPI_Transfer_Write(fd,txbuf,1) ;


        FPGA_SPI_WAIT_BUSY(fd) ;

        StartAddr = g_Global->FLASH_SEC_SIZE * ssec;				                //!<计算扇区的起始地址
        txbuf[0] = cmd[mode];
        txbuf[1] = (StartAddr >> 16)& 0xFF;
        txbuf[2] = (StartAddr >> 8)& 0xFF;
        txbuf[3] = (StartAddr >> 0)& 0xFF;

         SPI_Transfer_Write(fd,txbuf,4) ;
//         usleep(10);
         ssec += size[mode];

         FPGA_SPI_WAIT_BUSY(fd) ;
//         usleep(10);

    }
    if(name == FPGA_FLASH_VBYONE1){
        // *(unsigned short *)fpga_manage::p_fpga_manage->to_fpga1_spi_flash_sel =  GPIO47_CONTENT_H;
        g_FpgaManage->setGpioHigLow(3, 1, 0);
    }

    //*(unsigned short *)fpga_manage::p_fpga_manage->addr_gpio85 =  GPIO85_CONTENT_H;
    //*(unsigned short *)fpga_manage::p_fpga_manage->addr_gpio4 =  GPIO4_CONTENT_H;
    Utils::_spi_mutex.unlock();

    return (TRUE);


}






/**
 * @brief FPGA_SPI_FLASH_VBYONE_WRITE
 *
 * @param fd: fd
 * @param sec: sec of flash(must be care SndbufPt)
 * @param mode: SPI_FLASH_CMD_ERASE_4K/SPI_FLASH_CMD_ERASE_32K/SPI_FLASH_CMD_ERASE_64K
 * @param num:num of sec
 * @return
 */
Ouint8 fpga_drv::FPGA_SPI_FLASH_VBYONE_WRITE(Ouint8 name,Ouint32 Dst,Ouint8* SndbufPt,Ouint32 NByte)
{
    Ouint32 data_w,k,i=0;
    Ouint32 addr;
    int fd;

    if (((Dst+NByte > g_Global->FPGA_FLASH_VBYONE1_MAX_ADDR)||(NByte == 0))) return FALSE;

    Utils::_spi_mutex.lock();
    //system("echo 0 >/sys/class/gpio/gpio85/value");

//    usleep(10);
    if(name == FPGA_FLASH_VBYONE1){
        fd = fpga_manage::p_fpga_manage->fpga_vbyone1_flash_fd ;
        // *(unsigned short *)fpga_manage::p_fpga_manage->to_fpga1_spi_flash_sel =  GPIO47_CONTENT_L;
        g_FpgaManage->setGpioHigLow(3, 1, 0);
    }
//Utils::_system_mutex.unlock();
    //FPGA_SPI_Disable_WP(fd);

    data_w=Dst&0xFF;
    data_w=256-data_w;

    if(NByte>=data_w){
        NByte=NByte-data_w;

//        unsigned char * txbuf = new unsigned char[data_w + 4];

//        txbuf[0] = SPI_FLASH_CMD_WRITE_ENABLE ;
        SndbufPt[3] = SPI_FLASH_CMD_WRITE_ENABLE;
        SPI_Transfer_Write(fd,&SndbufPt[3],1) ;

        SndbufPt[0] = SPI_FLASH_CMD_WRITE;
        addr=Dst ;
        SndbufPt[1] = (addr >> 16)& 0xFF;
        SndbufPt[2] = (addr >> 8)& 0xFF;
        SndbufPt[3] = (addr >> 0)& 0xFF;
//        for(k = 0; k < data_w; k++)
//        {
//            txbuf[4+i] = SndbufPt[i] ;
//            i++;
//        }
        i= data_w;

        SPI_Transfer_Write(fd,SndbufPt,4+data_w) ;
        FPGA_SPI_WAIT_BUSY(fd) ;

//        BX_printf("\n FPGA_SPI_FLASH_VBYONE_WRITE 01 \n") ;

       // delete txbuf;
    }
    if(NByte>=256){
        data_w=NByte>>8;
//        BX_printf("\n FPGA_SPI_FLASH_VBYONE_WRITE 02 \n") ;
        for(k=0;k<data_w;k++){

//            unsigned char * txbuf = new unsigned char[256 + 4];

            SndbufPt[3 +i] = SPI_FLASH_CMD_WRITE_ENABLE ;
            SPI_Transfer_Write(fd,&SndbufPt[3 + i],1) ;

            SndbufPt[0+i] = SPI_FLASH_CMD_WRITE ;
            addr=Dst+i ;
            SndbufPt[1+i] = (addr >> 16)& 0xFF;
            SndbufPt[2+i] = (addr >> 8)& 0xFF;
            SndbufPt[3+i] = (addr >> 0)& 0xFF;
//            for(n = 0; n < 256; n++)
//            {
//                txbuf[4+i] = SndbufPt[i] ;
//                i++;
//            }
            SPI_Transfer_Write(fd,&SndbufPt[0+i],256+4) ;
            FPGA_SPI_WAIT_BUSY(fd) ;
            i += 256;

//            delete txbuf;
//            usleep(10);
        }

    }

    data_w=NByte&0xFF;
    if(data_w > 0){

        SndbufPt[3 +i] = SPI_FLASH_CMD_WRITE_ENABLE ;
        SPI_Transfer_Write(fd,&SndbufPt[3 +i],1) ;


        SndbufPt[0 +i] = SPI_FLASH_CMD_WRITE ;


        addr=Dst+i ;
        SndbufPt[1 +i] = (addr >> 16)& 0xFF;
        SndbufPt[2 +i] = (addr >> 8)& 0xFF;
        SndbufPt[3 +i] = (addr >> 0)& 0xFF;
//        for(n = 0; n < data_w; n++)
//        {
//            txbuf[4+i] = SndbufPt[i] ;
//            i++;
//        }

        SPI_Transfer_Write(fd,&SndbufPt[0 +i],4+data_w) ;

        FPGA_SPI_WAIT_BUSY(fd) ;

//        BX_printf("\n FPGA_SPI_FLASH_VBYONE_WRITE 04 \n") ;
//        delete txbuf;
    };
    if(name == FPGA_FLASH_VBYONE1){
        //*(unsigned short *)fpga_manage::p_fpga_manage->to_fpga1_spi_flash_sel =  GPIO47_CONTENT_H;
        g_FpgaManage->setGpioHigLow(3, 1, 0);
    }

//    usleep(10);
    //*(unsigned short *)fpga_manage::p_fpga_manage->addr_gpio85 =  GPIO85_CONTENT_H;
    //*(unsigned short *)fpga_manage::p_fpga_manage->addr_gpio4 =  GPIO4_CONTENT_H;
    Utils::_spi_mutex.unlock();
    return (TRUE);


}




Ouint8 fpga_drv::FPGA_SPI_FLASH_VBYONE_READ(Ouint8 name,Ouint32 Dst,Ouint32 NByte,Ouint8* RcvBufPt)
{
    Ouint32 i = 0;
    Ouint32 j = 0;
    Ouint32 k = 0;
    int fd;

    if ((Dst+NByte > g_Global->FPGA_FLASH_VBYONE1_MAX_ADDR)||(NByte == 0))	return FALSE;

    Utils::_spi_mutex.lock();
    //system("echo 0 >/sys/class/gpio/gpio85/value");

    if(name == FPGA_FLASH_VBYONE1){
        fd = fpga_manage::p_fpga_manage->fpga_vbyone1_flash_fd ;
        //*(unsigned short *)fpga_manage::p_fpga_manage->to_fpga1_spi_flash_sel =  GPIO47_CONTENT_L;
        g_FpgaManage->setGpioHigLow(3, 1, 0);
    }
    //Utils::_system_mutex.unlock();
    //int fpga_drv::SPI_Transfer(int fd ,const unsigned char *TxBuf, unsigned char *RxBuf, int len)
    unsigned char * txbuf = new unsigned char[NByte + 5];
    unsigned char *rxbuf = new unsigned char[NByte + 5] ;

    //max_len=0x800
    j = Dst;
    if(NByte > 0x800){
        for (k = 0; k < (NByte / 0x800) ; k++)
        {
            txbuf[0] = SPI_FLASH_CMD_FAST_READ ;
            txbuf[1] = (j >> 16)& 0xFF ;
            txbuf[2] = (j >> 8)& 0xFF ;
            txbuf[3] = (j >> 0)& 0xFF ;
            txbuf[4] = (0x00 >> 0)& 0xFF ;

            SPI_Transfer(fd ,txbuf ,rxbuf , 5 + 0x800) ;
            for (i = 0; i < 0x800; i++)
            {
                RcvBufPt[i + j - Dst] = rxbuf[5 + i];
            }

            j += 0x800;

        }

        if(NByte % 0x800)
        {
            txbuf[0] = SPI_FLASH_CMD_FAST_READ ;
            txbuf[1] = (j >> 16)& 0xFF ;
            txbuf[2] = (j >> 8)& 0xFF ;
            txbuf[3] = (j >> 0)& 0xFF ;
            txbuf[4] = (j >> 0)& 0xFF ;

            SPI_Transfer(fd ,txbuf ,rxbuf , (NByte % 0x800 + 5)) ;
            for (i = 0; i < (NByte % 0x800); i++)
            {
                RcvBufPt[i + k * 0x800] = rxbuf[5 + i];
            }



        }

    }else{

        txbuf[0] = SPI_FLASH_CMD_FAST_READ ;
        txbuf[1] = (Dst >> 16)& 0xFF ;
        txbuf[2] = (Dst >> 8)& 0xFF ;
        txbuf[3] = (Dst >> 0)& 0xFF ;
        txbuf[4] = (0x00 >> 0)& 0xFF ;

        SPI_Transfer(fd ,txbuf ,rxbuf , 5 + NByte) ;
        for (i = 0; i < NByte; i++)
        {
            RcvBufPt[i] = rxbuf[5+i];
        }
    }

    //Utils::_system_mutex.lock();
    if(name == FPGA_FLASH_VBYONE1){
        //*(unsigned short *)fpga_manage::p_fpga_manage->to_fpga1_spi_flash_sel =  GPIO47_CONTENT_H;
        g_FpgaManage->setGpioHigLow(3, 1, 1);
    }


    delete rxbuf;
    delete txbuf;
    rxbuf = NULL;
    txbuf = NULL;

    //*(unsigned short *)fpga_manage::p_fpga_manage->addr_gpio85 =  GPIO85_CONTENT_H;
    //*(unsigned short *)fpga_manage::p_fpga_manage->addr_gpio4 =  GPIO4_CONTENT_H;
    Utils::_spi_mutex.unlock();
    return (TRUE);

}



void fpga_drv::FPGA_SPI_FLASH_SSTF016B_RD_UID(Ouint8 name ,Ouint8* buf)
{
    int i;
    int fd;
    Utils::_spi_mutex.lock();
    //system("echo 0 >/sys/class/gpio/gpio85/value");

    if(name == FPGA_FLASH_VBYONE1){
        fd = fpga_manage::p_fpga_manage->fpga_vbyone1_flash_fd ;
        //*(unsigned short *)fpga_manage::p_fpga_manage->to_fpga1_spi_flash_sel =  GPIO47_CONTENT_L;
        g_FpgaManage->setGpioHigLow(3, 1, 0);
    }

    unsigned char * txbuf = new unsigned char[8 + 5];
    unsigned char *rxbuf = new unsigned char[8 + 5] ;

#if 1
    txbuf[0] = SPI_FLASH_CMD_READ_UID ;
    txbuf[1] = (0x00)& 0xFF ;
    txbuf[2] = (0x00)& 0xFF ;
    txbuf[3] = (0x00)& 0xFF ;
    txbuf[4] = (0x00)& 0xFF ;

    for(int i=0;i<8;i++){
        txbuf[5+i] = 0xFF;

    }

    SPI_Transfer(fd ,txbuf ,rxbuf , 5 + 8) ;


    for (i = 0; i < 8; i++)
    {
        buf[i] = rxbuf[5+i];
    }
#else


//    txbuf[0] = SPI_FLASH_CMD_FAST_READ ;
//    SPI_Transfer_Write(fd ,txbuf , 1) ;




    txbuf[0] = SPI_FLASH_CMD_READ_STATUS1;
    txbuf[1] = 0xff;
    txbuf[1] = 0xff;
    rxbuf[0] = 0x00;
    rxbuf[1] = 0xff;
    rxbuf[1] = 0xff;
    SPI_Transfer(fd,txbuf,rxbuf,2) ;

    BX_printf("\n FPGA_SPI_WAIT_BUSY   %#x  %#x %#x\n",rxbuf[0],rxbuf[1],rxbuf[2]) ;
#endif

    if(name == FPGA_FLASH_VBYONE1){
        // *(unsigned short *)fpga_manage::p_fpga_manage->to_fpga1_spi_flash_sel =  GPIO47_CONTENT_H;
        g_FpgaManage->setGpioHigLow(3, 1, 1);
    }

    //*(unsigned short *)fpga_manage::p_fpga_manage->addr_gpio85 =  GPIO85_CONTENT_H;
    //*(unsigned short *)fpga_manage::p_fpga_manage->addr_gpio4 =  GPIO4_CONTENT_H;

    delete rxbuf;
    delete txbuf;
    rxbuf = NULL;
    txbuf = NULL;
    Utils::_spi_mutex.unlock();
    //return (TRUE);
}






